[Android Tips] Support Library に追加された ActionBarActivity を使ってみた
Support Library に ActionBar のサポートが追加
7月24日に Android SDK 4.3 (APIレベル18) がリリースされ、ADT r18 がリリースされ、Support Library r18 がリリースされました。Support Library r18 では v7 で ActionBar が正式にサポートされました!
ということで新しく追加された ActionBarActivity を早速使ってみたのでメモしておきます。
Support Package v7 をインポートする
ActionBarActivity を使う上でまず必要なのが Support Package v7 です。このライブラリは Android 2.1 (APIレベル7) から使うことができます。Android Studio のプロジェクトであれば、build.gradle の dependencies に Support Package v7 のリポジトリを追加します。
build.gradle
dependencies { compile 'com.android.support:support-v4:13.0.+' compile 'com.android.support:appcompat-v7:18.0.+' }
これで ActionBar, ActionBarActivity (ついでに ShareActionProvider) が使えるようになりました。
ActionBarActivity を使う
それでは ActionBarActivity を使ってみましょう。まずはテーマに Theme.AppCompat か Theme.AppCompat.Light か Theme.AppCompat.Light.DarkActionBar を設定します。その他のテーマはこちらを参照してください。
<style name="AppBaseTheme" parent="Theme.AppCompat.Light"> </style>
あとは Activity の親を ActionBarActivity に差し替えます。
public class MainActivity extends ActionBarActivity { … }
これで終わりです。めっちゃ簡単ですね! 2.3.3 で実行してみました。
ActionBarActivity の ActionBar をいろいろカスタマイズする
せっかくなので色々試してみたいと思います。
タブを置いてみる
まずはタブを置いてみました。ActionBar の取得は getSupportActionBar() ですね。
ActionBar ab = getSupportActionBar(); ab.setNavigationMode(ActionBar.NAVIGATION_MODE_TABS); ab.addTab(ab.newTab().setText("Tab1").setTabListener(mTabListener)); ab.addTab(ab.newTab().setText("Tab2").setTabListener(mTabListener)); ab.addTab(ab.newTab().setText("Tab3").setTabListener(mTabListener));
実行結果
ドロップダウンリストを表示する
次にドロップダウンリスト形式のナビゲーションにしてみました。
ActionBar ab = getSupportActionBar(); ab.setDisplayShowTitleEnabled(false); ab.setNavigationMode(ActionBar.NAVIGATION_MODE_LIST); SpinnerAdapter adapter = ArrayAdapter.createFromResource( this, R.array.list, android.R.layout.simple_list_item_1); ab.setListNavigationCallbacks(adapter, new ActionBar.OnNavigationListener() { @Override public boolean onNavigationItemSelected(int i, long l) { return false; } });
実行結果
ちなみに Spinner が ICS のやつになってる!と思って見てみたら SpinnerICS というクラスを内部的に使っているみたいでした。このクラスは Internal なのでレイアウトでは使えませんでした。。
NavigationDrawer を使う
最近追加されたばかりの新しいナビゲーションパターンである NavigationDrawer を用いたナビゲーションも実装できます。まずは以下のようなレイアウトにします。
<android.support.v4.widget.DrawerLayout xmlns:android="http://schemas.android.com/apk/res/android" android:id="@+id/drawer_layout" android:layout_width="match_parent" android:layout_height="match_parent"> <!-- コンテンツ --> <FrameLayout android:id="@+id/content_frame" android:layout_width="match_parent" android:layout_height="match_parent" /> <!-- Navigation Drawer --> <ListView android:id="@+id/left_drawer" android:layout_width="240dp" android:layout_height="match_parent" android:layout_gravity="start" android:choiceMode="singleChoice" android:background="#eee" /> </android.support.v4.widget.DrawerLayout>
次に Activity の実装です。公式のサンプルと同じように実装しましょう。
package jp.classmethod.android.sample.actionbar; import android.content.res.Configuration; import android.os.Bundle; import android.support.v4.app.ActionBarDrawerToggle; import android.support.v4.view.GravityCompat; import android.support.v4.widget.DrawerLayout; import android.support.v7.app.ActionBar; import android.support.v7.app.ActionBarActivity; import android.view.MenuItem; import android.view.View; import android.widget.AdapterView; import android.widget.ArrayAdapter; import android.widget.ListView; public class MainActivity extends ActionBarActivity { private DrawerLayout mDrawerLayout; private ListView mDrawerList; private ActionBarDrawerToggle mDrawerToggle; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity_main); ActionBar ab = getSupportActionBar(); ab.setDisplayHomeAsUpEnabled(true); ab.setHomeButtonEnabled(true); // DrawerLayout mDrawerLayout = (DrawerLayout) findViewById(R.id.drawer_layout); mDrawerLayout.setDrawerShadow(R.drawable.drawer_shadow, GravityCompat.START); // DrawerListを開く/閉じるトグルボタン mDrawerToggle = new ActionBarDrawerToggle( this, mDrawerLayout, R.drawable.ic_drawer, R.string.open, R.string.close ); mDrawerLayout.setDrawerListener(mDrawerToggle); // DrawerList mDrawerList = (ListView) findViewById(R.id.left_drawer); ArrayAdapter adapter = ArrayAdapter.createFromResource( this, R.array.list, android.R.layout.simple_list_item_1); mDrawerList.setAdapter(adapter); mDrawerList.setOnItemClickListener(mOnItemClickListener); } private AdapterView.OnItemClickListener mOnItemClickListener = new AdapterView.OnItemClickListener() { @Override public void onItemClick(AdapterView<?> adapterView, View view, int i, long l) { // DrawerLayoutを閉じる mDrawerLayout.closeDrawer(mDrawerList); } }; @Override protected void onPostCreate(Bundle savedInstanceState) { super.onPostCreate(savedInstanceState); // DrawerToggleの状態を同期する mDrawerToggle.syncState(); } @Override public void onConfigurationChanged(Configuration newConfig) { super.onConfigurationChanged(newConfig); // DrawerToggleの状態を同期する mDrawerToggle.onConfigurationChanged(newConfig); } @Override public boolean onOptionsItemSelected(MenuItem item) { if (mDrawerToggle.onOptionsItemSelected(item)) { return true; } return super.onOptionsItemSelected(item); } }
ちなみにリソースに使っているアイコンも公式のサンプルからダウンロードできます。
これで実行すると以下のようになります!ActionBarSherlock だとそのままではアイコンが表示されなかったりしましたが、アニメーションも含めて正しく表示されました。
ActionBarSherlock から移行したい場合
ActionBarSherlock から移行する方法は以下にまとめられています。
ActionBarSherlock の API は標準 SDK の API に沿って実装されているので、テーマの定義と Activity と Fragment の親クラスの変更さえできればスムーズに移行可能できるようです。
まとめ
ActionBar が公式でサポートされたことにより、2系でも差し支えなく ActionBar を用いた実装ができるようになりました。今回は ActionBar の UI の実装を主に取り扱いましたがリファレンスを眺めてみると Up ナビゲーションのサポートも充実しているようでした(supportNavigateUpTo() やら onPrepareSupportNavigateUpTaskStack() やら)。
今後もバージョンアップしていくと思われるので、期待しましょう!
またデザインガイドラインをよく読んで、ユーザーが迷わないよう一貫したナビゲーションを提供するようにしましょう。